package net.feling.mcloud.connection;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import net.feling.mcloud.entity.Message;
import net.feling.mcloud.entity.User;
import net.feling.mcloud.utils.Config;
import net.feling.mcloud.utils.DefaultClientHandler;
import net.feling.mcloud.filter.UserCodecFactory;
import net.feling.mcloud.utils.DeviceUtil;
import net.feling.mcloud.utils.UserUtil;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.io.Serializable;
import java.net.ConnectException;
import java.net.InetSocketAddress;

public class ConnectService extends Service {
    private InetSocketAddress socketAddress;
    private NioSocketConnector connector;
    private ConnectFuture future;
    private IoSession ioSession = null;
    private Callback callback = null;
    private boolean isServiceAlive = false;
    private boolean isConnect = false;
    private boolean isTimeout = false;
    private boolean ifKeepAlive = false;
    //private Context context;
    private ReconnectionTread reconnectionTread;

    private MyBinder binder = new MyBinder();

    public class MyBinder extends Binder {
        public ConnectService getService() {
            return ConnectService.this;
        }

        public void setSocketAddress(InetSocketAddress socketAddress) {
            ConnectService.this.socketAddress = socketAddress;
        }

        public IoSession getServiceSession() {
            return ConnectService.this.ioSession;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        isServiceAlive = true;
        ifKeepAlive = true;
        Log.d("service Create", "第一次创建");
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        synchronized (this) {
            isTimeout = false;
        }
        try {
            if (!isConnect) {
                Log.d("service onStartCommand", "第一次启动");
                connect();
                keepAlive();
            }
        } catch (ConnectException e) {
            e.printStackTrace();
            Log.d("connect", "IP地址错误");

        } catch (Exception e) {
            e.printStackTrace();
            Log.d("connect", "未知错误");
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }


    /**
     * 建立连接，在子线程中完成
     *
     * @throws ConnectException
     */
    public synchronized void connect() throws ConnectException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                if (socketAddress != null) {
                    future = connector.connect();
                    //future.awaitUninterruptibly();
                    Log.d("socket", "address 不为空");
                    Log.d("address", "--ip-->" + socketAddress.getHostName());
                    Log.d("address", "--port-->" + socketAddress.getPort());

                    future.addListener(new IoFutureListener<ConnectFuture>() {
                        @Override
                        public void operationComplete(ConnectFuture mfuture) {
                            if (mfuture.isConnected()) {
                                Log.d("connetion", "连接成功");
                                isConnect = true;
                                ioSession = mfuture.getSession();
                                ioSession.setAttribute("id", "xiaomi");
                                Log.d("session in Service", ioSession.hashCode() + " ");
                                if (callback != null) {
                                    callback.onDataChange(isConnect);
                                    callback.onSessionCreate(ioSession);
                                    //ioSession.setAttribute("id","xiaomi");
                                    //Log.d("session in Service", ioSession.hashCode() + " ");
                                }
                            } else {
                                Log.d("connection", "连接失败");
                                isConnect = false;
                                isTimeout = true;
                                ifKeepAlive = false;
                            }
                        }
                    });
                }
            }
        });
        thread.start();
    }

    @Override
    public void onDestroy() {
        if (isServiceAlive && isConnect) {
            isServiceAlive = false;
            isConnect = false;
            ioSession.close(true);
            Log.d("service", "----->>onDestroy ");
        }
        Log.d("service", "onDestroy");
    }

    /**
     * 初始化连接参数
     */
    public void setConnector() {
        connector = new NioSocketConnector();
        connector.setHandler(new DefaultClientHandler());
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new UserCodecFactory()));
        connector.setDefaultRemoteAddress(socketAddress);
        connector.setConnectTimeout(10);
        isTimeout = false;
        isConnect = false;
        ifKeepAlive = true;
        Log.d("onBind", "重新初始化IP");
        //connector.setConnectTimeoutMillis(5000);

        //connector.setDefaultRemoteAddress(socketAddress);
    }


    /**
     * 发送心跳包，每个5秒发一次
     */
    public void keepAlive() {
        final Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (isServiceAlive && ifKeepAlive) {
                    if (isConnect) {
                        Log.d("心跳包", "启动了");
                        if (ioSession != null) {
                            try {
                                Config config = (Config) getApplicationContext();
                                User user = UserUtil.getUser(getApplicationContext());
                                Log.d("网络", user.getNetworkState() + "");
                                user.setBatteryLeft(config.getBatteryLeft());
                                Message<User> message = new Message();
                                message.setType("User");
                                message.setSender(DeviceUtil.getLocalMacAddress());
                                message.setContent(user);
                                ioSession.write(message);
                                Log.d("keepAlive", "心跳包");
                                Thread.sleep(5000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        });
        thread.start();
    }

    public synchronized void sendPackage(final Serializable objects) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                if (ioSession != null && ioSession.isConnected()) {
                    ioSession.write(objects);
                    Log.d("发送", "你好");
                }
            }
        });
        thread.start();
    }

    public boolean isConnected() {
        return isConnect;
    }

    public boolean isTimeout() {
        return isTimeout;
    }

    public interface Callback {
        void onDataChange(boolean mFlag);

        void onSessionCreate(IoSession session);
    }

}
